#!/usr/bin/env python2.4
# encoding: utf-8
# -*- coding: utf-8 -*-
# 
import gtk

try:
    import hildon
except ImportError, e:
    hildon = False

class View(object):
    def __init__(self):
        # main window
        self.win = self.get_win()
        self.vbox = gtk.VBox()
        self.menu = self.get_menu()
        toolbar = gtk.Toolbar()
        toolbar.set_style(gtk.TOOLBAR_ICONS)

        # menu file
        mnu_file = gtk.Menu()
        mnu_item_file = gtk.MenuItem("_File")
        mnu_item_file.set_submenu(mnu_file)
        self.menu.add(mnu_item_file)

        self.mnu_item_new = self._menuitem(gtk.STOCK_NEW, "_New...")
        self.mnu_item_open = self._menuitem(gtk.STOCK_OPEN, "_Open...")
        self.mnu_item_save = self._menuitem(gtk.STOCK_SAVE, "_Save...")
        self.mnu_item_save_as = self._menuitem(gtk.STOCK_SAVE_AS, "Save _as...")
        self.mnu_item_quit = self._menuitem(gtk.STOCK_QUIT, "_Quit...")
        mnu_file.add(self.mnu_item_new)
        mnu_file.add(self.mnu_item_open)
        mnu_file.add(self.mnu_item_save)
        mnu_file.add(self.mnu_item_save_as)
        mnu_file.add(gtk.SeparatorMenuItem())
        mnu_file.add(self.mnu_item_quit)

        self.tool_new = gtk.ToolButton(stock_id=gtk.STOCK_NEW)
        self.tool_open = gtk.ToolButton(stock_id=gtk.STOCK_OPEN)
        self.tool_save = gtk.ToolButton(stock_id=gtk.STOCK_SAVE)
        self.tool_save_as = gtk.ToolButton(stock_id=gtk.STOCK_SAVE_AS)
        toolbar.add(self.tool_new)
        toolbar.add(self.tool_open)
        toolbar.add(self.tool_save)
        toolbar.add(self.tool_save_as)

        # text editor
        scr_win = gtk.ScrolledWindow()
        self.text_view = gtk.TextView()
        self.text_buffer = self.text_view.get_buffer()
        scr_win.add(self.text_view)

        # final packs
        self.add_toolbar(toolbar)
        self.vbox.pack_start(scr_win, True)
        self.win.add(self.vbox)
        self.win.show_all()
        self.menu.show_all()

    def _menuitem(self, icon, txt):
        img_quit = gtk.Image()
        img_quit.set_from_stock(icon, gtk.ICON_SIZE_MENU)
        mnu_item = gtk.ImageMenuItem(txt)
        mnu_item.set_image(img_quit)
        return mnu_item

    def add_toolbar(self, toolbar):
        self.vbox.pack_start(toolbar, False)

    def get_menu(self):
        menu = gtk.MenuBar()
        self.vbox.pack_start(menu, False)
        return menu

    def error(self, txt):
        dialog = gtk.MessageDialog(self.win,
                   gtk.DIALOG_DESTROY_WITH_PARENT,
                   gtk.MESSAGE_ERROR,
                   gtk.BUTTONS_CLOSE, txt)
        dialog.connect("response", lambda d, r: dialog.destroy())
        dialog.show()

    def get_win(self):
        win = gtk.Window()
        win.resize(640, 480)
        win.set_title("Text Editor")
        return win

    def set_win_title(self, title):
        if title:
            self.win.set_title("Text Editor - %s" % (title))
        else:
            self.win.set_title("Text Editor")
            
    def ask(self, txt):
        md = gtk.MessageDialog(self.win,
                gtk.DIALOG_MODAL,
                gtk.MESSAGE_QUESTION,
                gtk.BUTTONS_OK_CANCEL,
                txt
        )
        resp = md.run()
        md.destroy()
        return resp == gtk.RESPONSE_OK

    def get_save_filename(self):
        dlg = gtk.FileChooserDialog("Salvar...", self.win,
                gtk.FILE_CHOOSER_ACTION_SAVE,
                buttons=(
                    gtk.STOCK_OK, gtk.RESPONSE_OK,
                    gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL
                )
            )

        dlg.set_local_only(True)
        resp = dlg.run()
        fname = dlg.get_filename()
        dlg.hide()
        if resp == gtk.RESPONSE_CANCEL:
            fname = ""
        return fname

    def get_open_filename(self):
        dlg = gtk.FileChooserDialog("Abrir...", self.win,
                gtk.FILE_CHOOSER_ACTION_OPEN,
                buttons=(
                    gtk.STOCK_OK, gtk.RESPONSE_OK,
                    gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL
                )
            )

        dlg.set_local_only(True)
        resp = dlg.run()
        fname = dlg.get_filename()
        dlg.hide()
        if resp == gtk.RESPONSE_CANCEL:
            fname = ""
        return fname
  
class HildonView(View):
    def get_win(self):
        self.app = hildon.App()
        win = hildon.AppView("")
        self.app.set_appview(win)
        self.app.set_title("Text Editor")
        self.app.show_all()
        return win

    def get_menu(self):
        menu = self.win.get_menu()
        menu.show_all()
        return menu

    def add_toolbar(self, toolbar):
        self.win.get_vbox().add(toolbar)

    def get_open_filename(self):
        dlg = hildon.FileChooserDialog(self.app,
                gtk.FILE_CHOOSER_ACTION_OPEN)
        resp = dlg.run()
        fname = dlg.get_filename()
        dlg.hide()
        if resp == gtk.RESPONSE_CANCEL:
            fname = ""
        return fname

    def get_save_filename(self):
        dlg = hildon.FileChooserDialog(self.app,
                gtk.FILE_CHOOSER_ACTION_SAVE)
        resp = dlg.run()
        fname = dlg.get_filename()
        dlg.hide()
        if resp == gtk.RESPONSE_CANCEL:
            fname = ""
        return fname

    def ask(self, txt):
        md = gtk.MessageDialog(self.app,
                gtk.DIALOG_MODAL,
                gtk.MESSAGE_QUESTION,
                gtk.BUTTONS_OK_CANCEL,
                txt
        )
        resp = md.run()
        md.destroy()
        return resp == gtk.RESPONSE_OK

    def error(self, txt):
        dialog = gtk.MessageDialog(self.app,
                   gtk.DIALOG_DESTROY_WITH_PARENT,
                   gtk.MESSAGE_ERROR,
                   gtk.BUTTONS_CLOSE, txt)
        dialog.connect("response", lambda d, r: dialog.destroy())
        dialog.show()

    def set_win_title(self, title):
        if title:
            self.win.set_title(title)
        else:
            self.win.set_title("Text Editor")
  
class App(object):
    def __init__(self):
        self.modified = False
        self._filename = ""
        if hildon:
            self.view = HildonView()
        else:
            self.view = View()

        self.text_buffer = self.view.text_buffer

        self.view.win.connect("destroy", self.quit)
        self.view.mnu_item_new.connect("activate", self.new)
        self.view.mnu_item_open.connect("activate", self.open_file)
        self.view.mnu_item_save.connect("activate", self.save_file)
        self.view.mnu_item_save_as.connect("activate", self.save_as_file)
        self.view.mnu_item_quit.connect("activate", self.quit)
        self.view.tool_new.connect("clicked", self.new)
        self.view.tool_open.connect("clicked", self.open_file)
        self.view.tool_save.connect("clicked", self.save_file)
        self.view.tool_save_as.connect("clicked", self.save_as_file)
        self.text_buffer.connect("changed", self.changed)

    def _getFilename(self):
        return self._filename
    def _setFilename(self, filename):
        self.view.set_win_title(filename)
        self._filename = filename
    filename = property(_getFilename, _setFilename)

    def changed(self, evt):
        self.modified = True

    def cont(self, txt):
        if self.modified:
            if not self.view.ask(txt):
                return False
        return True

    def new(self, evt):
        if self.cont("Os dados não foram salvos.\nDeseja continuar?"):
            self.text_buffer.set_text("")
            self.filename = ""
            self.modified = False

    def open_file(self, evt):
        if self.cont("Os dados não foram salvos.\nDeseja continuar?"):
            self.filename = self.view.get_open_filename()
            if not self.filename:
                return
            try:
                f = open(self.filename, "r")
            except IOError, e:
                self.view.error("Arquivo não encontrado!")
                self.filename = ""
                return
            self.view.text_buffer.set_text(f.read())
            self.modified = False
            f.close()

    def save_file(self, evt):
        if not self.filename:
            return self.save_as_file(evt)
        self.save()

    def save_as_file(self, evt):
        self.filename = self.view.get_save_filename()
        self.save()

    def save(self):
        if not self.filename:
            return
        try:
            f = open(self.filename, "w")
            f.write(self.text_buffer.get_text(
                self.text_buffer.get_start_iter(),
                self.text_buffer.get_end_iter()
            ))
            f.close()
        except IOError, e:
            self.view.error("Erro ao gravar arquivo %s!" % (self.filename))
            return
        self.modified = False

    def quit(self, evt):
        if self.cont("Os dados não foram salvos.\nDeseja sair mesmo assim?"):
            gtk.main_quit()

    def run(self):
        gtk.main()

if __name__ == '__main__':
    app = App()
    app.run()

# vim:ts=4:sw=4:et
